/**
 * 从右到左组合单参数函数。 最右边函数可以使用多个参数，因为它提供了签名得到的复合函数。
 *
 * @param funcs (arguments): 需要合成的多个函数。预计每个函数都接收一个参数。它的返回值
 * 将作为一个参数提供给它左边的函数，以此类推。例外是最右边的参数可以接受多个参数，因为它将
 * 为由此产生的函数提供签名。
 * （译者注：compose(funcA, funcB, funcC) 形象为 compose(funcA(funcB(funcC())))）
 *
 * @returns {Function} 从右到左把接收到的函数合成后的最终函数。
 */
export default function compose(...funcs) {
  //当 compose 不接收函数实参时，返回一个**返回第一个实参的函数**。
  //compose()('123', '234', '345'); 123'
  if (funcs.length === 0) {
    return arg => arg
  }

  //当 compose 接收 1 个函数实参时返回【该函数】
  if (funcs.length === 1) {
    return funcs[0]
  }

  /**
   * 当 compose 接收 1 个以上函数实参时返回一个【函数组合】。
   * 例如：`compose(funcA, funcB, funcC)(1, 2, 3)`
   * 等效于 `((...args) => funcA(funcB(funcC(...args))))(1, 2, 3)`
   */
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
